// gulp构建
//1.gulp是基于流的构建系统，gulp中的文件操作是基于流，包括读取流、转换流、写入流
//2.流程 src => pipe => dest
//3.gulp中pipe是转换流管道
const gulp = require('gulp')
const { src, dest, watch, parallel, series } = gulp //gulp内置方法
const rename = require('gulp-rename') //文件的重命名

// 一.处理样式任务，样式文件转换
// 1.gulp-less，可以转换less文件，如果使用sass预编译可以是使用 gulp-sass插件
// 2.gulp-clean-css  压缩css代码
// 3.gulp-rename  重命名文件
// 4.autoprefixer，插件可以自动生成兼容性更好的代码，css hack 解决css兼容方案
const less = require('gulp-less')
const cleancss = require('gulp-clean-css')
const autoprefixer = require('gulp-autoprefixer')
const style = () => {
  //流就是异步操作
  return src('./src/css/*.less', { base: 'src' }) //src的第二个参数接收一个对象，表示参考目录
    .pipe(less())
    .pipe(autoprefixer())  
    .pipe(cleancss())
    .pipe(rename({ extname: '.min.css' }))
    .pipe(dest('dist'))
}

// 二.脚本文件构建
// 1.gulp-babel @babel/core @babel/preset-env  降级js需要的插件
// 2.gulp-uglify js文件压缩
// const babel = require('gulp-babel')
// const uglify = require('gulp-uglify')
const script = () => {
  return src('./src/js/*.js', { base: 'src' })
    .pipe(
      babel({
        presets: ['@babel/env']
      })
    )
    .pipe(uglify())
    .pipe(rename({ extname: '.min.js' }))
    .pipe(dest('dist'))
}

//三.页面文件构建
//1.gulp-htmlmin 压缩html
const htmlmin = require('gulp-htmlmin')
const html = () => {
  return src('./src/index.html', { base: 'src' })
    .pipe(
      htmlmin({
        collapseWhitespace: true, //去除不必要空格
        minifyCSS: true, //压缩style标签内容
        minifyJS: true //压缩script标签内容
      })
    )
    .pipe(dest('dist'))
}

// 四.资源文件构建
// 一般资源文件都是直接拷贝，如果需要处理图片压缩可以使用gulp-imagemin插件
const image = () => {
  //路径后可以使用*号通配选择 一个*加文件后缀指定一个类型 两个**表示全部
  return src('./src/images/**', { base: 'src' }).pipe(dest('dist'))
}

// 五.清除文件
const del = require('del')
const clear = () => {
  return del('dist')
}

// 六.发布服务 browser-sync 热更新
const browser = require('browser-sync')
const host = browser.create()
const dev = () => {
  //监视不同类型文件变化执行响应任务，实时跟新页面
  watch('./src/index.html', html)
  watch('./src/styles/*.less', style)
  watch('./src/scripts/*.js', script)
  watch('./src/images/**', image)
  host.init({
    notify: false, //禁用浏览器右上角的 browserSync 提示
    files: 'dist/**', //监视dist下文件变化
    server: {
      baseDir: 'dist', //指定发布目录的任务
      routes: {
        '/node_modules': 'node_modules'
      }
    }
  })
}

//组合任务构建 打包
const build = series(clear, parallel(style, script, html, image))
//启动运行时
const serve = series(build, dev)
exports.build = build
exports.serve = serve
